﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Threading;

namespace RSS_Downloader
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }
        private void MainForm_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string filename = (e.Data.GetData(DataFormats.FileDrop) as string[])[0];
                if (Directory.Exists(filename))
                    txtDirectory.Text = filename;
            }
        }
        private void MainForm_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Link;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        private void btnChooseFolder_Click(object sender, EventArgs e)
        {
            if (txtDirectory.Text != "")
                folderBrowserDialog.SelectedPath = txtDirectory.Text;

            if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
            {
                txtDirectory.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.Save();
        }
        private void MainForm_Load(object sender, EventArgs e)
        {
            txtDirectory.DataBindings.Add("Text", Properties.Settings.Default, "LastDirectory");
            txtUrl.DataBindings.Add("Text", Properties.Settings.Default, "LastUrl");
            txtThreads.DataBindings.Add("Value", Properties.Settings.Default, "LastThreads");
        }

        private bool StuffEnabled
        {
            set
            {
                var controls = this.Controls.OfType<Control>()
                    .Where(x => x is Button 
                        || x is TextBox 
                        || x is NumericUpDown
                        || x is ListView);
                foreach (var c in controls)
                    c.Enabled = value;
            }
        }

        private void txtUrl_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                btnAdd_Click(sender, e);
                e.Handled = true;
            }
        }
        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (!workerFileFinder.IsBusy)
            {
                progressBar.Style = ProgressBarStyle.Marquee;
                progressBar.Value = 0;
                StuffEnabled = false;
                workerFileFinder.RunWorkerAsync(txtUrl.Text);
            }
        }

        private void workerFileFinder_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                e.Result = Tools.GetAllFilesFrom(new Uri(e.Argument as string, UriKind.Absolute)).ToArray();
            }
            catch (Exception err)
            {
                e.Cancel = true;
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void workerFileFinder_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar.Style = ProgressBarStyle.Continuous;
            StuffEnabled = true;

            if (e.Result != null && e.Result is MediaFile[])
            {
                MediaFile[] files = e.Result as MediaFile[];

                fileList.Items.AddRange(files
                    .Select(x => new MediaFileListViewItem(x))
                    .Except(fileList.Items.OfType<MediaFileListViewItem>(), new MediaFileListViewItemComparer())
                    .ToArray()
                    );

                fileList.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
            }
            else
                MessageBox.Show("No files found in feed.", "Empty feed", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }


        private void bntDownload_Click(object sender, EventArgs e)
        {
            if (!downloadWorker.IsBusy)
            {
                btnDownload.Image = Properties.Resources.rss_delete;
                progressBar.Style = ProgressBarStyle.Continuous;
                progressBar.Value = 0;
                StuffEnabled = false;
                btnDownload.Enabled = true;
                downloadWorker.RunWorkerAsync(fileList.Items
                    .OfType<MediaFileListViewItem>()
                    .Where(x => x.Checked)
                .ToArray());
            }
            else
            {
                downloadWorker.CancelAsync();
            }

        }

        private void downloadWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get the list of files
            List<MediaFile> files = new List<MediaFile>();
            if (e.Argument is MediaFileListViewItem[])
                files.AddRange((e.Argument as MediaFileListViewItem[]).Select(x => x.MediaFile));

            // Check if we have any at all
            if (files.Count < 1)
            {
                MessageBox.Show("No files to download", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // Check for cancellation
            if (downloadWorker.CancellationPending) { e.Cancel = true; return; }

            // Build list of tasks

            // Start worker threads

            // Wait for worker threads to finish

            // End
            //e.Result = failed downloads;

        }            
        private void downloadWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;

            if (e.UserState is MediaFileDownloadCompletedArgs)
            {
                var userState = (MediaFileDownloadCompletedArgs)e.UserState;
                    foreach (ListViewItem i in fileList.Items)
                    {
                        if (i.Text == ((MediaFile)e.UserState).Uri.AbsoluteUri)
                            if (userState.Succeeded)
                                i.Remove();
                            else
                                i.Checked = false;
                    }
            }
        }
        private void downloadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnDownload.Image = Properties.Resources.rss_go;
            StuffEnabled = true;
            if (e.Cancelled)
            {
                MessageBox.Show("Operation Cancelled.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                // TODO: Show failed ones if needed.
            }
        }


    }
}
